﻿using ASmile;
using ASmile.Extend;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace ASmile.Extern.Lib.HttpCore
{
    public class HttpServer
    {
        public string RequestUri { set; get; }
        /// <summary>
        /// 服务器请求的缓存，最大10M
        /// </summary>
        protected virtual byte[] DataBuffer { get; } = new byte[1024 * 1024 * 10];

        public List<IHttpResponse> ResponseList { get; } = new List<IHttpResponse>();

        public void Start()
        {
            HttpListener listener = new HttpListener();
            listener.Prefixes.Add(RequestUri);
            listener.Start();
            LogHelper.LogObj.Info($"开起服务监听,url:{RequestUri} ");
            while (true)
            {
                HttpListenerContext context = listener.GetContext();
                //可以只绑定1个或多个地址，允许访问
                LogHelper.LogObj.Info($"访问:{context.Request.RawUrl}，来自：{context.Request.RemoteEndPoint}");
                Task.Factory.StartNew(HttpContextHandle, context);
            }
        }

        void HttpContextHandle(object contextObj)
        {
            HttpListenerContext context = contextObj as HttpListenerContext;

            var query = context.Request.QueryString;
            var ip = context.Request.RemoteEndPoint.Address.ToString();
            var port = context.Request.RemoteEndPoint.Port;

            //LogHelper.LogObj.Info($"URL: {context.Request.RawUrl} {context.Request.HttpMethod} 来自：{context.Request.RemoteEndPoint} ");
            //LogHelper.LogObj.Info($"IP: {ip}, port: {port}"); // 通过IP来限制访问
            //LogHelper.LogObj.Info($"Request.HttpMethod：{context.Request.HttpMethod}");

            var repType = context.Request.QueryString.Get("type");

            if (repType.StringEquals("TEST"))
            {
                ResponseText(context, "OK");
                return;
            }

            var rep = ResponseList?.Find(s => s.Type.StringEquals(repType));

            context.Response.ContentType = "application/json";
            context.Response.ContentEncoding = Encoding.UTF8;
            if (rep == null)
            {
                var msg = $"未找到指定 类型对象: {repType}";
                LogHelper.LogObj.Info(msg);
                ResponseStatus(context, HttpStatusCode.BadRequest, msg);
                return;
            }

            int offset = 0;
            using (Stream resStream = context.Request.InputStream)
            {
                int d;
                do
                {
                    if (offset > DataBuffer.Length)
                    {
                        LogHelper.LogObj.Error($"请求数据超出了限制长度：{DataBuffer.Length},");
                        context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                        context.Response.OutputStream.Dispose();
                        return;
                    }
                    d = resStream.ReadByte();
                    if (d == -1) break;
                    DataBuffer[offset] = (byte)d;
                    offset++;
                }
                while (true);
            }
            try
            {
                rep.ReceiveData(context, DataBuffer, 0, offset);
            }
            catch (Exception ex)
            {
                LogHelper.LogObj.Error("处理 ReceiveData 发生异常", ex);
                ResponseStatus(context, HttpStatusCode.InternalServerError, $"处理 ReceiveData 发生异常,{ex.Message}");
            }
        }
        /// <summary>
        /// 返回字节流
        /// </summary>
        protected void ResponseBytes(HttpListenerContext context, byte[] data)
        {
            try
            {
                using (context.Response.OutputStream)
                {
                    if (data != null && data.Length > 0)
                    {
                        context.Response.OutputStream.Write(data, 0, data.Length);
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.LogObj.Error("响应数据流出错", ex);
            }
        }
        /// <summary>
        /// 返回文本内容
        /// </summary>
        protected void ResponseText(HttpListenerContext context, string data)
        {
            byte[] d;
            if (data.IsNotEmpty())
            {
                d = Encoding.UTF8.GetBytes(data);
            }
            else
            {
                d = null;
            }
            ResponseBytes(context, d);
        }
        /// <summary>
        /// 仅发送状态码
        /// </summary>
        protected void ResponseStatus(HttpListenerContext context, HttpStatusCode status, string statusText = null)
        {
            context.Response.StatusCode = ((int)status);
            if (statusText.IsEmpty())
            {
                statusText = status.ToString();
            }
            context.Response.StatusCode = ((int)status);
            ResponseText(context, statusText);
        }
    }
}